import 'dart:async';

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_demo/ex/object.dart';
import 'package:flutter_demo/generated/assets.dart';
import 'package:flutter_demo/pages/page_with_title.dart';
import 'package:flutter_demo/widgets/app_widgets.dart';

class PageViewPage extends PageWithTitle {
  const PageViewPage({super.key}) : super("分页视图容器(PageView)");

  @override
  List<Widget> buildContentWidgets(BuildContext context) {
    return const [
      PrimaryTitle("简介"),
      BodyText("类似Android的ViewPager，为应用提供分页切换效果，常用于教学流程、主界面分页、"
          "图片浏览、图片轮播等场景"),
      AppSpacer.large,
      _Example(),
      AppSpacer.mini,
      UlItem("PageView"),
      BodyText("图片轮播是比较杂的需求，我们以其为例展示分页视图的使用方法"),
      LabelText("- scrollDirection 滚动方向，支持横向、纵向"),
      LabelText("- reverse 反转布局，从结束位置开始排布"),
      LabelText("- controller 分页控制器"),
      LabelText("    - initialPage 初始显示页面"),
      LabelText("    - keepPage 状态保存，重建组件后将从上次位置开始显示，忽略初始页面，若"
          "不保存刷新组件后将从initialPage开始"),
      LabelText("    - viewportFraction 视窗比例，分页占容器的宽度比例，默认是铺满"),
      LabelText("    - page 当前页（progress）"),
      LabelText("    - animateToPage 以动画的形式滚动到目标页面"),
      LabelText("    - jumpToPage 直接定位到目标页面"),
      LabelText("    - nextPage 下一页"),
      LabelText("    - previousPage 上一页"),
      LabelText("- physics 控制组件怎么响应用户滚动（例如可以不响应来防止用户滑动）"),
      LabelText("- pageSnapping 分页捕捉，在用户停止操作后，最近分页滚动到组件中心"),
      LabelText("- onPageChanged 简单监听当前显示的分页序列改变，更复杂的监听需要通过控制器去实现"),
      LabelText("- children 分页组件"),

      AppSpacer.large,
      UlItem("NotificationListener"),
      BodyText("我们借助它来监听用户是否在滚动PageView，以实现在用户手动滚动浏览时不触发定时切换下一页"),
    ];
  }
}

class _Example extends StatefulWidget {
  const _Example();

  @override
  State<StatefulWidget> createState() {
    return _ExampleState();
  }
}

class _ExampleState extends State<_Example> {
  final _pageChildren = [
    Image.asset(
      Assets.imagesBenxi,
      fit: BoxFit.cover,
    ),
    ColorFiltered(
      colorFilter: const ColorFilter.matrix([
        0.393,
        0.769,
        0.189,
        0,
        0,
        0.349,
        0.686,
        0.168,
        0,
        0,
        0.272,
        0.534,
        0.131,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
      ]),
      child: Image.asset(
        Assets.imagesBenxi,
        fit: BoxFit.cover,
      ),
    ),
    ColorFiltered(
      colorFilter: const ColorFilter.matrix([
        0.2126,
        0.7152,
        0.0722,
        0,
        0,
        0.2126,
        0.7152,
        0.0722,
        0,
        0,
        0.2126,
        0.7152,
        0.0722,
        0,
        0,
        0,
        0,
        0,
        1,
        0,
      ]),
      child: Image.asset(
        Assets.imagesBenxi,
        fit: BoxFit.cover,
      ),
    ),
  ];
  // final _pageChildren = List.generate(40, (index) {
  //   return Image.asset(
  //     Assets.imagesBenxi,
  //     fit: BoxFit.cover,
  //   );
  // });
  final _pageController = PageController(initialPage: 1);
  final _indicatorSize = 10.0;
  var _isUserScrolling = false;

  @override
  void initState() {
    super.initState();
    _pageController.addListener(() {
      //实现循环滚动
      if (_pageController.page == 0) {
        _pageController.jumpToPage(_pageChildren.length);
      } else if (_pageController.page == _pageChildren.length + 1) {
        _pageController.jumpToPage(1);
      }
      //更新指示器
      setState(() {});
    });
    Future.doWhile(() async {
      await Future.delayed(const Duration(seconds: 1));
      if (mounted) {
        if (!_isUserScrolling) {
          _pageController.nextPage(
            duration: const Duration(milliseconds: 300),
            curve: Curves.ease,
          );
        }
        return true;
      } else {
        return false;
      }
    });
  }

  @override
  void dispose() {
    _pageController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 16 / 9,
      child: Stack(
        children: [
          NotificationListener(
            onNotification: (notification) {
              if (notification is UserScrollNotification) {
                _isUserScrolling =
                    notification.direction != ScrollDirection.idle;
              }
              // else if(notification is ScrollEndNotification){
              //   isUserScrolling = false;
              // }
              return true;
            },
            child: PageView(
              controller: _pageController,
              children: List.generate(_pageChildren.length + 2, (index) {
                if (index == 0) {
                  return _pageChildren.last;
                } else if (index == _pageChildren.length + 1) {
                  return _pageChildren.first;
                } else {
                  return _pageChildren[index - 1];
                }
              }),
            ),
          ),
          LayoutBuilder(
            builder: (context, constraints) {
              final containerSize =
                  constraints.constrain(Size(double.infinity, _indicatorSize));
              final itemWidthCount =
                  (_pageChildren.length + 2) * _indicatorSize;
              var recommendItemSpaceSize = 0.0;
              if (itemWidthCount < containerSize.width) {
                recommendItemSpaceSize =
                    (containerSize.width - itemWidthCount) /
                        (_pageChildren.length + 1);
                if (recommendItemSpaceSize > _indicatorSize) {
                  recommendItemSpaceSize = _indicatorSize;
                }
              }
              final contentWidth = itemWidthCount +
                  recommendItemSpaceSize * (_pageChildren.length + 1);
              final offsetX = (containerSize.width - contentWidth) / 2;
              List<Widget> items = [];
              for (int index = 1; index < _pageChildren.length + 1; index++) {
                items.add(Positioned(
                  left: offsetX +
                      _indicatorSize * index +
                      recommendItemSpaceSize * index,
                  bottom: _indicatorSize,
                  child: InkWell(
                    onTap: () {
                      _pageController.animateToPage(index,
                          duration: const Duration(milliseconds: 300),
                          curve: Curves.ease);
                    },
                    child: Container(
                      width: _indicatorSize,
                      height: _indicatorSize,
                      decoration: BoxDecoration(
                          color: Theme.of(context).colorScheme.outline,
                          shape: BoxShape.circle),
                    ),
                  ),
                ));
              }
              //当前位置
              _pageController.page?.let((index) {
                items.add(Positioned(
                  left: offsetX +
                      _indicatorSize * index +
                      recommendItemSpaceSize * index,
                  bottom: _indicatorSize,
                  child: InkWell(
                    child: Container(
                      width: _indicatorSize,
                      height: _indicatorSize,
                      decoration: BoxDecoration(
                          color: Theme.of(context).colorScheme.primary,
                          shape: BoxShape.circle),
                    ),
                  ),
                ));
              });
              return Stack(children: items);
            },
          ),
        ],
      ),
    );
  }
}
